package de.wbh.gwt.form.layouter.gwt.di;

import javax.inject.Singleton;

import com.google.gwt.activity.shared.Activity;
import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.inject.client.AbstractGinModule;
import com.google.gwt.inject.client.assistedinject.GinFactoryModuleBuilder;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.inject.Provides;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.SimpleEventBus;

import de.wbh.gwt.form.layouter.gwt.dnd.Boundary;
import de.wbh.gwt.form.layouter.gwt.ui.view.EditPositionsViewImpl;
import de.wbh.gwt.form.layouter.gwt.ui.view.FieldsViewImpl;
import de.wbh.gwt.form.layouter.gwt.ui.view.LoadConfigurationViewImpl;
import de.wbh.gwt.form.layouter.gwt.ui.view.LoadFieldsViewImpl;
import de.wbh.gwt.form.layouter.gwt.ui.view.LoadPdfViewImpl;
import de.wbh.gwt.form.layouter.gwt.ui.view.LoadStepsViewImpl;
import de.wbh.gwt.form.layouter.gwt.ui.view.SaveConfigurationViewImpl;
import de.wbh.gwt.form.layouter.gwt.ui.view.SkeletonViewImpl;
import de.wbh.gwt.form.layouter.gwt.ui.view.StartViewImpl;
import de.wbh.gwt.form.layouter.shared.AppPlaceHistoryMapper;
import de.wbh.gwt.form.layouter.shared.SkeletonView;
import de.wbh.gwt.form.layouter.shared.activity.ActivityFactory;
import de.wbh.gwt.form.layouter.shared.activity.EditPositions;
import de.wbh.gwt.form.layouter.shared.activity.EditPositionsActivity;
import de.wbh.gwt.form.layouter.shared.activity.EditPositionsView;
import de.wbh.gwt.form.layouter.shared.activity.Fields;
import de.wbh.gwt.form.layouter.shared.activity.FieldsActivity;
import de.wbh.gwt.form.layouter.shared.activity.FieldsView;
import de.wbh.gwt.form.layouter.shared.activity.LoadConfiguration;
import de.wbh.gwt.form.layouter.shared.activity.LoadConfigurationActivity;
import de.wbh.gwt.form.layouter.shared.activity.LoadConfigurationView;
import de.wbh.gwt.form.layouter.shared.activity.LoadFields;
import de.wbh.gwt.form.layouter.shared.activity.LoadFieldsActivity;
import de.wbh.gwt.form.layouter.shared.activity.LoadFieldsView;
import de.wbh.gwt.form.layouter.shared.activity.LoadPdf;
import de.wbh.gwt.form.layouter.shared.activity.LoadPdfActivity;
import de.wbh.gwt.form.layouter.shared.activity.LoadPdfView;
import de.wbh.gwt.form.layouter.shared.activity.LoadSteps;
import de.wbh.gwt.form.layouter.shared.activity.LoadStepsActivity;
import de.wbh.gwt.form.layouter.shared.activity.LoadStepsView;
import de.wbh.gwt.form.layouter.shared.activity.SaveConfiguration;
import de.wbh.gwt.form.layouter.shared.activity.SaveConfigurationActivity;
import de.wbh.gwt.form.layouter.shared.activity.SaveConfigurationView;
import de.wbh.gwt.form.layouter.shared.activity.Start;
import de.wbh.gwt.form.layouter.shared.activity.StartActivity;
import de.wbh.gwt.form.layouter.shared.activity.StartView;
import de.wbh.gwt.form.layouter.shared.area.Deck1ContentArea;
import de.wbh.gwt.form.layouter.shared.area.Deck1ContentAreaActivityMapper;
import de.wbh.gwt.form.layouter.shared.area.Deck2LeftArea;
import de.wbh.gwt.form.layouter.shared.area.Deck2LeftAreaActivityMapper;
import de.wbh.gwt.form.layouter.shared.area.Deck2RightArea;
import de.wbh.gwt.form.layouter.shared.area.Deck2RightAreaActivityMapper;
import de.wbh.gwt.form.layouter.shared.place.Default;
import de.wbh.gwt.form.layouter.shared.place.StartPlace;

public class AppGinModule extends AbstractGinModule {

	@Override
	protected void configure() {
		bind(Place.class).annotatedWith(Default.class).to(StartPlace.class);
		bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);

		// bind views
		bind(SkeletonView.class).to(SkeletonViewImpl.class).in(Singleton.class);
		bind(StartView.class).to(StartViewImpl.class).in(Singleton.class);
		bind(LoadStepsView.class).to(LoadStepsViewImpl.class).in(Singleton.class);
		bind(LoadPdfView.class).to(LoadPdfViewImpl.class).in(Singleton.class);
		bind(LoadFieldsView.class).to(LoadFieldsViewImpl.class).in(Singleton.class);
		bind(SaveConfigurationView.class).to(SaveConfigurationViewImpl.class).in(Singleton.class);
		bind(FieldsView.class).to(FieldsViewImpl.class).in(Singleton.class);
		bind(EditPositionsView.class).to(EditPositionsViewImpl.class).in(Singleton.class);
		bind(LoadConfigurationView.class).to(LoadConfigurationViewImpl.class).in(Singleton.class);

		// bind activities
		install(new GinFactoryModuleBuilder()

		.implement(Activity.class, Start.class, StartActivity.class)

		.implement(Activity.class, LoadSteps.class, LoadStepsActivity.class)

		.implement(Activity.class, LoadPdf.class, LoadPdfActivity.class)

		.implement(Activity.class, LoadFields.class, LoadFieldsActivity.class)

		.implement(Activity.class, SaveConfiguration.class, SaveConfigurationActivity.class)

		.implement(Activity.class, Fields.class, FieldsActivity.class)

		.implement(Activity.class, EditPositions.class, EditPositionsActivity.class)

		.implement(Activity.class, LoadConfiguration.class, LoadConfigurationActivity.class)

		.build(ActivityFactory.class));

		// bind activity mapper
		bind(ActivityMapper.class).annotatedWith(Deck1ContentArea.class).to(Deck1ContentAreaActivityMapper.class);
		bind(ActivityMapper.class).annotatedWith(Deck2LeftArea.class).to(Deck2LeftAreaActivityMapper.class);
		bind(ActivityMapper.class).annotatedWith(Deck2RightArea.class).to(Deck2RightAreaActivityMapper.class);
	}

	@Provides
	@Deck1ContentArea
	@Singleton
	ActivityManager createDeck1ContentAreaActivityManager(@Deck1ContentArea ActivityMapper activityMapper, EventBus eventBus) {
		return new ActivityManager(activityMapper, eventBus);
	}

	@Provides
	@Deck2LeftArea
	@Singleton
	ActivityManager createDeck2LeftAreaActivityManager(@Deck2LeftArea ActivityMapper activityMapper, EventBus eventBus) {
		return new ActivityManager(activityMapper, eventBus);
	}

	@Provides
	@Deck2RightArea
	@Singleton
	ActivityManager createDeck2RightAreaActivityManager(@Deck2RightArea ActivityMapper activityMapper, EventBus eventBus) {
		return new ActivityManager(activityMapper, eventBus);
	}

	@Provides
	@Singleton
	PlaceController createPlaceController(EventBus eventBus) {
		return new PlaceController(eventBus);
	}

	@Provides
	@Singleton
	PlaceHistoryHandler createPlaceHistoryHandler(AppPlaceHistoryMapper mapper, PlaceController placeController, EventBus eventBus, @Default Place defaultPlace) {
		PlaceHistoryHandler placeHistoryHandler = new PlaceHistoryHandler(mapper);
		placeHistoryHandler.register(placeController, eventBus, defaultPlace);
		return placeHistoryHandler;
	}

	@Provides
	@Boundary
	AbsolutePanel getBoundaryPanel(SkeletonView skeletonView) {
		return skeletonView.getDragArea();
	}
}
